package com.shangxia.dreaming.business;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.fastjson.JSON;
import com.shangxia.dreaming.business.pojo.AgeCount;
import com.shangxia.dreaming.business.pojo.IndexStatus;
import com.shangxia.dreaming.business.pojo.Model;
import com.shangxia.dreaming.business.pojo.TempData;
import com.shangxia.dreaming.common.content.ConditionContent;
import com.shangxia.dreaming.common.content.FileContentEnum;
import com.shangxia.dreaming.common.util.excelUtil.HeadFactory;
import com.shangxia.dreaming.common.util.excelUtil.ReadExcelUtil;
import com.shangxia.dreaming.common.util.excelUtil.WriteExcel;
import com.shangxia.dreaming.common.util.excelUtil.WriteHandler.MyEasyWriteHandler;
import com.shangxia.dreaming.common.util.excelUtil.WriteHandler.MyPurpleAllWriteHandler;
import com.shangxia.dreaming.common.util.excelUtil.WriteHandler.MyPurpleAllWriteHandler2;
import com.shangxia.dreaming.common.util.excelUtil.listener.NoModelDataListener;
import com.shangxia.dreaming.common.util.txtUtil.ReadTXT;
import com.shangxia.dreaming.common.util.txtUtil.WriteTXT;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.io.File;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;

import static com.shangxia.dreaming.common.content.ConditionContent.*;
import static com.shangxia.dreaming.common.util.txtUtil.ReadTXT.*;
import static java.util.Comparator.comparingInt;

/**
 * @ProjectName: dreaming
 * @ClassName: SecondJob
 * @Time: 2020/10/10
 * @Author: zhouy
 * @Description:
 * @Experience:
 */

@Slf4j
@Component
public class FourJob {
    @Resource
    private PrePareJob prePareJob = new PrePareJob();

    public void work() throws IOException, CloneNotSupportedException {

        //读取真号
        List<List<Integer>> realCodeLists = ReadTXT.readList_List_int();
        List<List<Integer>> realCodeLists1 = new ArrayList<>();
        List<List<Integer>> realCodeLists2 = new ArrayList<>();
        List<List<Integer>> realCodeLists3 = new ArrayList<>();
        for (int i = 0; i < realCodeLists.size(); i++) {
            ArrayList<Integer> list1 = new ArrayList<>();
            ArrayList<Integer> list2 = new ArrayList<>();
            ArrayList<Integer> list3 = new ArrayList<>();
            List<Integer> list = realCodeLists.get(i);
            list1.add(list.get(0));
            list2.add(list.get(1));
            list3.add(list.get(2));
            realCodeLists1.add(list1);
            realCodeLists2.add(list2);
            realCodeLists3.add(list3);
        }

        //最大翻表层数
        int limit = Math.min(realCodeLists.size(), MUST_TURN_TABLE_COLUMN);

        //翻表
        List<Integer>[][] arr1 = prePareJob.turnTable0(realCodeLists1, realCodeLists1.size(), 1, SUM_CODE_LENGTH);
        List<Integer>[][] arr2 = prePareJob.turnTable0(realCodeLists2, realCodeLists2.size(), 1, SUM_CODE_LENGTH);
        List<Integer>[][] arr3 = prePareJob.turnTable0(realCodeLists3, realCodeLists3.size(), 1, SUM_CODE_LENGTH);
        WriteExcel.exportRangeColumnExcel(arr1, 1, 10, 1, 10,0);
        WriteExcel.exportRangeColumnExcel(arr2, 1, 10, 1, 10,2);
        WriteExcel.exportRangeColumnExcel(arr3, 1, 10, 1, 10,3);

        String[][] IndexStrArr = new String[realCodeLists3.size()][realCodeLists3.size()];
        List<Map<String, List<Integer>>> realCodeIndexList = new ArrayList<>();

        for (int i = 0; i < limit; i++) {
            realCodeIndexList.add(new HashMap<>());
        }
        //中奖期数及层数
        Map<Integer, List<Integer>> winPrizeMap = new HashMap<>();
        for (int column = 0; column < realCodeLists1.size(); column++) {
            if (column % 100 == 0) {
                log.info("计算第" + (column + 1) + "层");
            }
            for (int row = 1; row < realCodeLists1.size(); row++) {
                if (row < column) {
                    continue;
                }
                Integer realIndex1 = -1;
                Integer realIndex2 = -1;
                Integer realIndex3 = -1;
                if (guessTrue(arr1, column, row, realIndex1) && guessTrue(arr2, column, row, realIndex2) && guessTrue(arr3, column, row, realIndex3)) {
                    IndexStrArr[row][column] = column + "," + realIndex1 + "," + realIndex2 + "," + realIndex3;
                    Map<String, List<Integer>> stringListMap = realCodeIndexList.get(column);
                    if (stringListMap.containsKey(realIndex1 + "," + realIndex2 + "," + realIndex3)) {
                        stringListMap.get(realIndex1 + "," + realIndex2 + "," + realIndex3).add(row);
                    } else {
                        List<Integer> list = new ArrayList<>();
                        list.add(row);
                        stringListMap.put(realIndex1 + "," + realIndex2 + "," + realIndex3, list);
                    }
                    if (winPrizeMap.containsKey(row)) {
                        winPrizeMap.get(row).add(column);
                    } else {
                        List<Integer> list = new ArrayList<>();
                        list.add(column);
                        winPrizeMap.put(row, list);
                    }
                }
            }
        }

        List<Integer> sortList = new ArrayList<>(winPrizeMap.keySet());
        sortList.sort(comparingInt(o -> o));

        //相对最后一期中奖数据

        List<Model> lastModels = new ArrayList<>();
        for (Map.Entry<Integer, List<Integer>> entry : winPrizeMap.entrySet()) {
            Integer row = entry.getKey();
            List<Integer> columns = entry.getValue();
            for (Integer column : columns) {
                String realCodes = IndexStrArr[row][column];
                Map<String, List<Integer>> stringListMap = realCodeIndexList.get(column);
                List<Integer> list = stringListMap.get(realCodes);
                if (null == list) {
                    continue;
                } else if (list.size() > 1) {
                    for (int i = 1; i < list.size(); i++) {
                        Model model = new Model();
                        model.setRow(row);
                        model.setIndexStr(realCodes);
                        model.setColumn(column);
                        model.setAge(list.get(i) - list.get(i - 1));
                        //设置真号
                        String[] split = realCodes.split(",");
                        int realCode1 = Integer.parseInt(split[0]);
                        int realCode2 = Integer.parseInt(split[1]);
                        int realCode3 = Integer.parseInt(split[2]);
                        int nowColumn = column;
                        while (nowColumn > 0) {
                            realCode1 = arr1[row][nowColumn - 1].get(realCode1);
                            realCode2 = arr2[row][nowColumn - 1].get(realCode2);
                            realCode3 = arr3[row][nowColumn - 1].get(realCode3);
                            nowColumn--;
                        }
                        model.setRealIndexStr(realCode1 + "," + realCode2 + "," + realCode3);
                        lastModels.add(model);
                    }
                    lastModels.add(lastModel(arr1, row, column, realCodes, list.get(arr1.length - list.size()), arr2[arr1.length - 1], arr3[arr1.length - 1]));
                } else if (list.size() == 1) {
                    lastModels.add(lastModel(arr1, row, column, realCodes, list.get(arr1.length - list.size()), arr2[arr1.length - 1], arr3[arr1.length - 1]));
                }
            }
        }
        Map<Integer, List<Model>> collect = lastModels.stream().sorted(comparingInt(Model::getRow)).collect(Collectors.groupingBy(Model::getRow));
        List<List<String>> resultLists = new ArrayList<>();
        int maxSize = 0;
        for (Map.Entry<Integer, List<Model>> entry : collect.entrySet()) {
            List<String> list = new ArrayList<>();
            list.add(entry.getKey() + "");
            List<Model> value = entry.getValue();
            maxSize = Math.max(maxSize, value.size());
            for (Model model : value) {
                //位置	年龄	真号	层数
                list.add(model.getIndexStr());
                list.add(model.getAge() + "");
                list.add(model.getRealIndexStr() + "");
                list.add(model.getColumn() + "");
                list.add(" ");
            }
            resultLists.add(list);
        }
        saveResult(resultLists, maxSize, "超过结果");
    }

    private void saveResult(List<List<String>> resultLists, int maxSize, String fileName) {
        File file = new File(PATH_Result + fileName + FileContentEnum.EXCEL_END);
        if (file.exists()) {
            file.delete();
        }
        EasyExcel.write(file).head(HeadFactory.head1(maxSize)).sheet("超过结果").registerWriteHandler(new MyPurpleAllWriteHandler()).doWrite(resultLists);
    }

    private Model lastModel(List<Integer>[][] arr1, Integer row, Integer column, String realCodes, Integer age, List<Integer>[] lists, List<Integer>[] lists1) {
        Model model = new Model();
        model.setRow(arr1.length);
        model.setIndexStr(realCodes);
        model.setColumn(column);
        model.setAge(age);
        String[] split = realCodes.split(",");
        int realCode1 = Integer.parseInt(split[0]);
        int realCode2 = Integer.parseInt(split[1]);
        int realCode3 = Integer.parseInt(split[2]);
        int nowColumn = column;
        while (nowColumn > 0) {
            realCode1 = arr1[arr1.length - 1][nowColumn - 1].get(realCode1);
            realCode2 = lists[nowColumn - 1].get(realCode2);
            realCode3 = lists1[nowColumn - 1].get(realCode3);
            nowColumn--;
        }
        model.setRealIndexStr(realCode1 + "," + realCode2 + "," + realCode3);
        return model;
    }

    private Boolean guessTrue(List<Integer>[][] arr1, int column, int row, Integer realIndex) {
        if (column == row) {
            return false;
        }
        List<Integer> list = arr1[row][column];
        Integer trueInt = list.get(list.size() - 1);
        int trueIndex = 0;

        trueIndex = arr1[row - 1][column].indexOf(trueInt) + 1;

        realIndex = groupIndex(trueInt);
        if (realIndex == groupIndex(trueIndex)) {
            return true;
        }
        realIndex = -1;
        return false;
    }

    private int groupIndex(int index) {
        switch (index) {
            case 0:
            case 1:
                return 1;
            case 2:
            case 3:
                return 2;
            case 4:
            case 5:
                return 3;
            case 6:
            case 7:
                return 4;
            default:
                return 5;
        }
    }


}
